import { Component, OnInit, EventEmitter, Input, Output, ViewChild, TemplateRef, ChangeDetectorRef } from '@angular/core';
// import { PropertyChangeObject } from '@farris/ide-property-panel';
import { MessagerService } from '@farris/ui-messager';
import { NotifyService } from '@farris/ui-notify';
import { TreeTableComponent } from '@farris/ui-treetable';
import { cloneDeep } from 'lodash-es';
import { DesignerHostSettingService, DomService } from '@farris/designer-services';
import { debounceTime } from 'rxjs/operators';
import { PropertyChangeObject } from '../../entity/property-entity';

/**
 * 提供一个左树右属性面板的编辑器
 */
@Component({
  selector: 'collection-with-property-editor',
  templateUrl: './collection-with-property-editor.component.html',
  styleUrls: ['./collection-with-property-editor.component.css']
})
export class CollectionWithPropertyEditorComponent implements OnInit {
  @Output() closeModal = new EventEmitter<any>();
  @Output() submitModal = new EventEmitter<any>();

  @Input() value;
  @Input() editorParams: CollectionWithPropertyEditorParam;

  @ViewChild('footer') modalFooter: TemplateRef<any>;
  @ViewChild('tt') treeTable: TreeTableComponent;

  get modalConfig() {
    return {
      title: this.editorParams.modalTitle || '编辑器',
      width: 700,
      height: 700,
      showButtons: true
    };
  }

  /** 属性面板配置项 */
  propertyConfig;
  /** 属性值 */
  propertyData;
  /** 是否显示属性面板 */
  showPropertyPanel = false;


  treeData = [];
  treeCols = [];
  /** 当前选中行 */
  selectedNode;
  /** 选中行在树中的层级 */
  selectedNodeLayer = 0;

  /** 禁用子级节点 */
  disableChildItem = false;

  /** 记录编辑器刚打开时的DOM actions数据。编辑器内部交互面板在操作过程中可能会修改actions节点，导致点击【取消】按钮时无法还原actions数据。所以这里记录一份原始数据，方便还原。 */
  private previousActions: any[];

  /** 记录编辑器刚打开时的DOM viewmodels数据。编辑器内部交互面板在操作过程中可能会修改viewmodels节点，导致点击【取消】按钮时无法还原viewmodels数据。所以这里记录一份原始数据，方便还原。 */
  private previousViewModels: any[];

  /** 触发编辑器的保存操作 */
  private triggerModalSave: any;

  constructor(
    private designerHostSettingService: DesignerHostSettingService,
    private domService: DomService,
    private notifyService: NotifyService,
    private msgService: MessagerService,
    private cd: ChangeDetectorRef) { }

  ngOnInit() {

    this.modalConfig.title = this.editorParams.modalTitle || '列表项集合编辑器';
    this.treeCols = [{ field: this.editorParams.textKey, title: '名称' }];



    this.previousActions = cloneDeep(this.domService.module.actions);
    this.previousViewModels = cloneDeep(this.domService.module.viewmodels);

    this.triggerModalSave = () => this.clickConfirm();

    if (this.editorParams.maxCascadeLevel === 1) {
      this.disableChildItem = true;
    }
    if (!this.value || this.value.length === 0) {
      this.treeData = [];
      return;
    }


    const value = cloneDeep(this.value);
    this.treeData = this.assembleData(value);

    // 默认选中第一行
    const sub = this.treeTable.loadedData.asObservable().pipe(
      debounceTime(200)
    ).subscribe(() => {
      if (this.treeData.length) {
        const firstDataId = this.treeData[0].data.id;
        this.treeTable.selectNode(firstDataId);

        // 只订阅一次
        sub.unsubscribe();
      }

    });
  }

  private assembleData(data) {
    const treeData = [];
    data.forEach(item => {
      const itemData = {
        data: item,
        children: [],
        expanded: true
      };
      if (this.editorParams.childrenKey && item[this.editorParams.childrenKey]) {
        itemData.children = this.assembleData(item[this.editorParams.childrenKey]);
      }
      treeData.push(itemData);
    });

    return treeData;
  }


  onNodeSelected(e) {
    this.selectedNode = e.node;
    this.selectedNodeLayer = e.parents && e.parents.length || 0;
    this.triggerPropertyPanel();
  }

  private triggerPropertyPanel() {
    this.propertyConfig = [];
    if (this.editorParams.getPropertyConfig) {
      this.propertyData = this.selectedNode.data;
      this.propertyConfig = this.editorParams.getPropertyConfig(this.selectedNode, this.triggerModalSave);

      this.showPropertyPanel = true;
    } else {
      this.showPropertyPanel = false;
    }
  }

  /**
   * 新增同级
   */
  addSiblingItem() {
    const newNode = this.createNewNode();

    if (this.selectedNode && this.selectedNode.parent) {
      this.selectedNode.parent.children.push(newNode);
    } else {
      // 没有选中元素，则在根节点添加
      this.treeData.push(newNode);
    }

    this.reloadTreeData(newNode.data.id, this.selectedNodeLayer);
  }
  /**
   * 新增子级
   */
  addChildItem() {
    if (!this.selectedNode) {
      this.notifyService.warning('请先选择节点');
      return;
    }

    if (this.selectedNodeLayer + 1 >= this.editorParams.maxCascadeLevel) {
      this.notifyService.warning('最多允许' + this.editorParams.maxCascadeLevel + '级节点');
      return;
    }

    const newNode = this.createNewNode();
    if (!this.selectedNode.children) {
      this.selectedNode.children = [];
    }
    this.selectedNode.children.push(newNode);

    this.reloadTreeData(newNode.data.id, this.selectedNodeLayer + 1);
  }

  private createNewNode() {
    const controlService = this.designerHostSettingService.controlService;

    const metadata = controlService.getControlMetaData(this.editorParams.controlType);

    if (this.editorParams.defaultControlValue) {
      Object.assign(metadata, cloneDeep(this.editorParams.defaultControlValue));
    }
    const radomNum = Math.random().toString().slice(2, 6);

    metadata[this.editorParams.idKey] = metadata[this.editorParams.idKey] + '_' + radomNum;
    metadata[this.editorParams.textKey] = metadata[this.editorParams.textKey] + '_' + radomNum;

    return {
      data: metadata,
      children: [],
      expanded: true
    };
  }
  /**
   * 下移
   */
  moveDownItem() {
    if (!this.selectedNode) {
      this.notifyService.warning('请先选择要移动的节点');
      return;
    }

    const parentNode = this.selectedNode.parent;
    const siblingsData = parentNode ? parentNode.children : this.treeData;
    const index = siblingsData.findIndex(node => node.data.id === this.selectedNode.data.id);

    // 上级节点的最后一个====> 不动
    if (index === siblingsData.length - 1) {
      return;
    }
    siblingsData.splice(index, 1);
    siblingsData.splice(index + 1, 0, this.selectedNode);


    this.reloadTreeData();

  }
  /**
   * 上移
   */
  moveUpItem() {
    if (!this.selectedNode) {
      this.notifyService.warning('请先选择要移动的节点');
      return;
    }

    const parentNode = this.selectedNode.parent;
    const siblingsData = parentNode ? parentNode.children : this.treeData;
    const index = siblingsData.findIndex(node => node.data.id === this.selectedNode.data.id);

    // 第一个节点====> 不动
    if (index === 0) {
      return;
    }
    siblingsData.splice(index, 1);
    siblingsData.splice(index - 1, 0, this.selectedNode);


    this.reloadTreeData();
  }

  /**
   * 删除
   */
  removeItem() {
    if (!this.selectedNode) {
      this.notifyService.warning('请先选择要删除的节点');
      return;
    }

    if (this.selectedNode.children && this.selectedNode.children.length > 0) {
      this.msgService.question('【' + this.selectedNode.data[this.editorParams.textKey] + '】包含下级节点，确认级联删除？', () => {
        this.confirmDeleteItem();
      }, () => {
        return;
      });
    } else {
      this.confirmDeleteItem();
    }

  }

  private confirmDeleteItem() {

    const parentNode = this.selectedNode.parent;
    const siblingsData = parentNode ? parentNode.children : this.treeData;
    const index = siblingsData.findIndex(node => node.data.id === this.selectedNode.data.id);

    siblingsData.splice(index, 1);

    this.selectedNode = null;
    this.reloadTreeData();

    this.showPropertyPanel = false;
  }

  private reloadTreeData(newTargetId?: string, targetLevel?: number) {
    this.treeTable.loadData(this.treeData);

    // 重新选中行
    let targetNode;
    if (newTargetId) {
      this.treeTable.selectNode(newTargetId);
      this.selectedNodeLayer = targetLevel;
    } else if (this.selectedNode) {
      targetNode = this.treeTable.findRowNode(this.selectedNode.data.id);
      if (targetNode) {
        targetNode.isSelected = true;
      }
    }


  }
  propertyChanged(changeObject: PropertyChangeObject) {
    const textKey = this.editorParams.textKey;
    if (changeObject.propertyID === textKey) {

      this.treeTable.update(
        this.selectedNode.id,
        { [textKey]: changeObject.propertyValue });

      this.updateControlMap();
    }

    // 保存新增的变量
    this.addNewVariableToViewModel(changeObject, this.editorParams.viewModelId);

  }
  /**
   * 新版属性编辑器，在编辑过程中可能会新增变量，此处需要将新增的变量追加到ViewModel中
   */
  private addNewVariableToViewModel(changeObject: PropertyChangeObject, viewModelId: string) {
    const newPropertyValue = changeObject.propertyValue;
    if (newPropertyValue && newPropertyValue.isNewVariable && typeof newPropertyValue === 'object' &&
      newPropertyValue.type === 'Variable') {
      // 如果有则加入新变量
      delete newPropertyValue.isNewVariable;
      const newVar = {
        id: newPropertyValue.field,
        category: 'locale',
        code: newPropertyValue.path,
        name: newPropertyValue.path,
        type: newPropertyValue.newVariableType || 'String'
      };
      delete newPropertyValue.newVariableType;
      const viewModel = this.domService.getViewModelById(viewModelId);
      if (!viewModel.states.find(s => s.id === newVar.id)) {
        viewModel.states.push(newVar);
      }
    }
  }

  onPropertyModalChanged(e) {

    this.addControlMapForEventPath(e);
  }

  private addControlMapForEventPath(e) {
    const changeObject: PropertyChangeObject = e.changeObject;
    const param = e.parameters;

    // 交互面板有变更时，触发更新事件路径
    if (changeObject.categoryId !== 'eventsEditor' || !param || !param.events || !param.events.length) {
      return;
    }
    // 若没有父级控件id，则不设置事件路径
    if (!this.editorParams.parentNodeId) {
      return;
    }

    this.updateControlMap();


    // const parentPath = this.domService.controlBasicInfoMap.get(this.editorParams.parentNodeId);
    // if (parentPath) {
    //   const nodeText = this.selectedNode.data[this.editorParams.textKey];
    //   this.domService.controlBasicInfoMap.set(this.selectedNode.data.id, {
    //     showName: nodeText,
    //     parentPathName: `${parentPath.parentPathName} > ${nodeText}`
    //   });
    // }

  }

  private updateControlMap() {
    if (!this.editorParams.parentNodeId) {
      return;
    }
    const parentPath = this.domService.controlBasicInfoMap.get(this.editorParams.parentNodeId);
    if (parentPath) {
      const nodeText = this.selectedNode.data[this.editorParams.textKey];
      this.domService.controlBasicInfoMap.set(this.selectedNode.data.id, {
        showName: nodeText,
        parentPathName: `${parentPath.parentPathName} > ${nodeText}`
      });
    }
  }
  /**
   * 取消
   */
  clickCancel() {

    this.domService.module.actions = this.previousActions;
    this.domService.module.viewmodels = this.previousViewModels;

    this.closeModal.emit();
  }


  /**
   * 确定
   */
  clickConfirm() {
    // 使用模式切换为弹出帮助的按钮，需要创建隐藏区域
    // if (this.toolbarItemProp.needOpenHelpMap.size > 0) {
    //   this.toolbarItemProp.needOpenHelpMap.forEach(itemPropertyData => {
    //     this.toolbarItemProp.handleOpenHelpMode(itemPropertyData, this.editorParams.parentNodeId, this.editorParams.viewModelId);
    //   });

    // }

    if (this.editorParams.beforeSave) {
      this.editorParams.beforeSave();
    }
    const newValue = this.getValueArray(this.treeData);
    this.submitModal.emit({ value: newValue });
  }

  private getValueArray(treeNode: any[]) {
    const originalDataArray = [];
    treeNode.forEach(treeData => {
      const originalData = treeData.data;

      if (treeData.children && this.editorParams.childrenKey) {
        const childrenData = this.getValueArray(treeData.children);
        originalData[this.editorParams.childrenKey] = childrenData;
      }

      originalDataArray.push(originalData);
    });

    return originalDataArray;
  }
}


class CollectionWithPropertyEditorParam {

  modalTitle: string;
  viewModelId: string;

  /** 节点对应的控件类型 */
  controlType: string;
  /** 新增节点的默认值 */
  defaultControlValue?: any;

  parentNodeId?: string;

  idKey: string;
  textKey: string;

  // 多级节点的场景下，必需。
  childrenKey?: string;

  /** 节点级数，不传则认为不限制 */
  maxCascadeLevel?: number;

  /** 获取单行数据对应的属性面板配置 */
  getPropertyConfig: (selectedNode: any, triggerModalSave?: any) => {};

  /** 保存前方法 */
  beforeSave: () => {};

  /** 隐藏工具栏，用于只配置属性，不新增或删除 */
  disableToolbar?: boolean;

  /** 触发模板编辑器的保存方法 */
  triggerModalSave?: any;
}
